package com.hyk.service.impl;

import cn.hutool.core.lang.Snowflake;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hyk.domain.EntrustOrder;
import com.hyk.domain.Market;
import com.hyk.dto.AccountDto;
import com.hyk.dto.UserDto;
import com.hyk.feign.AccountFeign;
import com.hyk.feign.UserServiceFeign;
import com.hyk.mapper.EntrustOrderMapper;
import com.hyk.model.EntrustOrderParam;
import com.hyk.service.EntrustOrderService;
import com.hyk.service.MarketService;
import com.hyk.utils.UserUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

@Service
public class EntrustOrderServiceImpl extends ServiceImpl<EntrustOrderMapper, EntrustOrder> implements EntrustOrderService{

    @Autowired
    private MarketService marketService;

    @Resource
    private AccountFeign accountFegin;

    @Autowired
    private UserServiceFeign userServiceFeign;

    private Snowflake snowflake = new Snowflake(5,1);

    @Override
    public void buy(EntrustOrderParam entrustorderParam) {
        //获取用户的总交易buycoin数量
        BigDecimal allprice = new BigDecimal(entrustorderParam.getVolume()).multiply(new BigDecimal(entrustorderParam.getPrice()));

        Market market = marketService.getOne(new LambdaQueryWrapper<Market>()
                .eq(Market::getSymbol, entrustorderParam.getSymbol()));
        //校验单笔委托量是否符合设定值
        if(new BigDecimal(entrustorderParam.getVolume()).compareTo(market.getNumMin()) < 0){
            throw new IllegalArgumentException("当前委托单小于最小委托量");
        }
        if(new BigDecimal(entrustorderParam.getVolume()).compareTo(market.getNumMax()) > 0){
            throw new IllegalArgumentException("当前委托单大于最大委托量");
        }

        //判断当前用户资金是否足够
        AccountDto account = accountFegin.getUserAccountByCoinId(market.getBuyCoinId(), UserUtils.getUser());
        if (account.getBalanceAmount().compareTo(allprice)<0){
            throw new IllegalArgumentException("账户可用余额不足");
        }

        //构建对象
        EntrustOrder entrustOrder = new EntrustOrder();
        entrustOrder.setAmount(new BigDecimal(entrustorderParam.getVolume()));
//        entrustOrder.setBaseCoinRate();
//        entrustOrder.setContractUnit();
        entrustOrder.setCreated(new Date());
        entrustOrder.setDeal(BigDecimal.ZERO);

        entrustOrder.setFee(allprice.multiply(market.getFeeBuy()));
        entrustOrder.setFeeRate(market.getFeeBuy());
        entrustOrder.setFreeze(allprice);
        entrustOrder.setLastUpdateTime(new Date());
        entrustOrder.setLockMargin(BigDecimal.ZERO);
        entrustOrder.setMarginRate(BigDecimal.ZERO);
        entrustOrder.setMarketId(market.getId());
        entrustOrder.setMarketName(market.getName());
        entrustOrder.setMarketType(market.getType());

        String depth = market.getMergeDepth();
        List<String> depthList = Arrays.asList(depth.split(","));
        Collections.sort(depthList);

        int i = Integer.parseInt(depthList.get(0));
        //直接删除多余的小数位，如2.35会变成2.3 setScale(1,BigDecimal.ROUND_DOWN)
        BigDecimal deptVoLow = new BigDecimal(entrustorderParam.getPrice()).setScale(i, BigDecimal.ROUND_DOWN);

        int p = Integer.parseInt(depthList.get(2));
        BigDecimal deptVoHig = new BigDecimal(entrustorderParam.getPrice()).setScale(p, BigDecimal.ROUND_DOWN);

        entrustOrder.setMergeHighPrice(deptVoHig);
        entrustOrder.setMergeLowPrice(deptVoLow);
        entrustOrder.setPrice(new BigDecimal(entrustorderParam.getPrice()));
        entrustOrder.setPriceType((byte)2);
        entrustOrder.setStatus((byte)0);
        entrustOrder.setSymbol(entrustorderParam.getSymbol());
        entrustOrder.setType((byte)1);
        entrustOrder.setId(snowflake.nextId());
        entrustOrder.setUserId(UserUtils.getUser());
        entrustOrder.setVolume(new BigDecimal(entrustorderParam.getVolume()));
        save(entrustOrder);

        //将用户的 buy coinId -》 可用余额 转入冻结余额

        Boolean aBoolean = accountFegin.transferUserLock(market.getBuyCoinId(), UserUtils.getUser(), allprice, entrustOrder.getId());
        if(!aBoolean){
            throw new IllegalArgumentException("用户资金转入冻结失败");
        }
    }

    @Override
    public Page<EntrustOrder> listForPage(Page<EntrustOrder> page,Byte type, Long userId, Long id, String userName, String startTime, String endTime, Byte status, String mobile, Long marketId,String symbol) {
        List<Long> ids = new ArrayList<>();
        Map<Long, UserDto> users = new HashMap<>();
        if(userId != null || StringUtils.isNotBlank(userName) || StringUtils.isNotBlank(mobile)){
            users = userServiceFeign.getBasicUsers(Arrays.asList(userId), mobile, userName);
            if (users == null){
                return page;
            }
            Set<Map.Entry<Long, UserDto>> set = users.entrySet();
            for(Map.Entry<Long, UserDto> map : set){
                ids.add(map.getKey());

            }
        }

        Page<EntrustOrder> list = page(page, new LambdaQueryWrapper<EntrustOrder>()
                .in(!CollectionUtils.isEmpty(ids), EntrustOrder::getUserId, ids)
                .eq(type != null && type != (byte)0, EntrustOrder::getType, type)
                .eq(id != null, EntrustOrder::getId, id)
                .ge(StringUtils.isNotBlank(startTime), EntrustOrder::getCreated, startTime)
                .le(StringUtils.isNotBlank(endTime), EntrustOrder::getCreated, endTime)
                .eq(status != null, EntrustOrder::getStatus, status)
                .eq(marketId != null,EntrustOrder::getMarketId,marketId)
                .eq(StringUtils.isNotBlank(symbol) && symbol != "0",EntrustOrder::getSymbol,symbol)
                .orderByDesc(EntrustOrder::getCreated));
        List<EntrustOrder> records = list.getRecords();

        if (CollectionUtils.isEmpty(ids)){
            for(EntrustOrder entrustOrder : records){
                ids.add(entrustOrder.getUserId());
            }
            if (!CollectionUtils.isEmpty(ids)){
                users = userServiceFeign.getBasicUsers(ids,null,null);
            }
        }
        for(EntrustOrder entrustOrder : records){
            UserDto userDto = users.get(entrustOrder.getUserId());
            if (userDto != null){
                entrustOrder.setUserName(userDto.getUsername());
                entrustOrder.setMobile(userDto.getMobile());
            }else{
                entrustOrder.setUserName("未知用户");
                entrustOrder.setMobile("无");
            }
        }
        return  list;
    }
}
